﻿using Resource;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;

namespace SqlSugarFirst
{
    /// <summary>
    /// SqlSugar映射
    /// </summary>
    public class Program
    {
        private static SqlSugarClient db = null;
        public static void Main(string[] args)
        {
            try
            {
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine("Hello World!");
                Console.WriteLine($"开始生成实体 {DateTime.Now.ToString("yyyy-MM-dd HH:mm:FF")}");
                var modelpath = @"Models\{0}";
                var path = Directory.GetCurrentDirectory();
                path = path.Substring(0, path.IndexOf(@"\bin"));
                path = $"{path.Substring(0, path.LastIndexOf(@"\") + 1)}{modelpath}";
                Dictionary<string, string> tabledic = new Dictionary<string, string>();
                //("库名", "表名"); ALL=库所有表
                //tabledic.Add("OUSB", "JOB_HEAD");
                tabledic.Add("TEXT", "datemtl");
                //tabledic.Add("OUSB", "ALL");
                //tabledic.Add("ERP_PROD", "ALL");
                //tabledic.Add("Test_Demo","PPACKINFOR");
                //tabledic.Add("TEST2", "USER_INFOR2000000");
                //tabledic.Add("TEST3", "USER_INFOR3000001");
                DbFirst(path, tabledic);
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }

        /// <summary>
        /// 根据表生产实体
        /// </summary>
        /// <param name="path"></param>
        public static void DbFirst(string path, Dictionary<string, string> tabledic)
        {
            List<string> basename = tabledic.Keys.ToList();
            List<string> tablename = tabledic.Values.ToList();
            //db.DbFirst.IsCreateAttribute().CreateClassFile(path);
            for (int i = 0; i < basename.Count; i++)
            {
                db = SugarFactory.GetInstance(basename[i].ToString(), false);
                //获取表  
                List<DbTableInfo> list = db.DbMaintenance.GetTableInfoList().Where(x => tablename.Contains("ALL") ? x.Name.IsNormalized() : tablename.Contains(x.Name.Trim())).ToList();
                //获取视图
                List<DbTableInfo> viewList = db.DbMaintenance.GetViewInfoList().Where(x => tablename.Contains("ALL") ? x.Name.IsNormalized() : tablename.Contains(x.Name.Trim().ToUpper())).ToList();
                var allList = list.Concat(viewList);

                //循环所有的表和视图 他们属于同一个类 DbTableInfo
                int dtsucount = 0;
                int dtfaicount = 0;
                List<string> faitable = new List<string>();
                foreach (DbTableInfo table in allList)
                {
                    try
                    {
                        string table_name = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(table.Name.ToLower()).Replace("_", "");
                        //映射表增加 实体名称 和表名称
                        db.MappingTables.Add(table_name, table.Name);
                        //根据表名 获取所有表字段
                        List<DbColumnInfo> dd = db.DbMaintenance.GetColumnInfosByTableName(table.Name);
                        var @base = tabledic.FirstOrDefault(q => tablename.Contains("ALL") ? q.Value == "ALL" : q.Value == table.Name).Key;
                        foreach (DbColumnInfo item in dd)
                        {
                            string columnname = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(item.DbColumnName.ToLower()).Replace("_", "");
                            //item.DbColumnName.ToLower();
                            //映射字段添加 （字段名，字段名，表名）
                            db.MappingColumns.Add(columnname, columnname, table_name);
                        }
                        db.DbFirst.
                        SettingClassTemplate(old =>
                        {
                            string snp = "\r\n    ";
                            var sugartable = GetClassTemplate().Replace("{SugarTable}", @$"{snp}[Tenant(""{@base}"")]{snp}[SugarTable(""{table.Name}"",""{@base}"")]");
                            return sugartable;
                        })
                        .SettingNamespaceTemplate(old =>
                        {
                            return old;
                        })
                        .SettingPropertyDescriptionTemplate(old =>
                        {
                            //自定义的模板
                            //GetPropertyDescriptionTemplate();
                            return old;
                        })
                        .SettingPropertyTemplate((columns, temp, type) =>
                        {
                            string comp = "\r\n           ";
                            var columnattribute = $"{comp}[SugarColumn({{0}})]";
                            List<string> attributes = new List<string>();
                            if (columns.IsPrimarykey)
                                attributes.Add("IsPrimaryKey=true");
                            if (columns.IsIdentity)
                                attributes.Add("IsIdentity=true");
                            if (attributes.Count == 0)
                                columnattribute = string.Empty;
                            List<string> customattributes = new List<string>();
                            if (!columns.IsNullable)
                                customattributes.Add($@"{comp}[Required(ErrorMessage =""{string.Format(Msg.Required, columns.DbColumnName)}"" )]");
                            if (!columns.DataType.ToLower().Equals("int"))
                                customattributes.Add($@"{comp}[StringLength({columns.Length}, ErrorMessage =""{string.Format(Msg.Length, columns.DbColumnName, columns.Length)}"" )]");

                            var t = temp.Replace("{PropertyType}", type)
                                    .Replace("{PropertyName}", CultureInfo.CurrentCulture.TextInfo.ToTitleCase(columns.DbColumnName.ToLower()))
                                    .Replace("{SugarColumn}", attributes.Count > 0 ? string.Format(columnattribute, string.Join(",", attributes)) : string.Join("", customattributes));
                            return t;
                        })
                        .SettingConstructorTemplate(old =>
                        {
                            return old;
                        })//.IsCreateAttribute().Where(table.Name).CreateClassFile(path);
                        .IsCreateAttribute().Where(name => name.Equals(table.Name)).CreateClassFile(path.Replace("{0}", table.DbObjectType.ToString()));
                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.WriteLine($"正在生成：dbbase：{basename[i].ToString()}；table：{table.Name}");
                        dtsucount++;
                    }
                    catch (Exception ex)
                    {
                        dtfaicount++;
                        faitable.Add(table.Name);
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine($"生成错误：dbbase：{basename[i].ToString()}；table：{table.Name}");
                        //Console.WriteLine($"Message:{ex.Message}");
                        continue;
                    }

                }
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine($"dbbase：{basename[i].ToString()}生成完毕  成功：{dtsucount};失败：{dtfaicount}");
                Console.WriteLine($"失败列表：{String.Join(",", faitable)}");
                dtsucount = 0;
            }
            Console.WriteLine("生成成功");
        }

        /// <summary>
        /// 命名空间的模板
        /// </summary>
        /// <returns></returns>
        public static string GetClassTemplate()
        {
            return @"using System.ComponentModel.DataAnnotations;
{using}
namespace {Namespace}
{
{ClassDescription}{SugarTable}
    public class {ClassName}
    {
           public {ClassName}() { }

{Constructor}{PropertyName}
    }
}
";
        }

        /// <summary>
        /// 字段的模板
        /// </summary>
        /// <returns></returns>
        public static string GetPropertyDescriptionTemplate()
        {
            return @"
           /// <summary>
           /// Remark:{PropertyDescription}
           /// Default:{DefaultValue}
           /// Nullable:{IsNullable}
           /// </summary>";
        }

        /// <summary>
        /// 根据实体生成表
        /// </summary>
        public static void SqlSugarCodeFirst()
        {
            var sqlSugarClient = SugarFactory.GetInstance("SAE_OFN", false);
            sqlSugarClient.DbMaintenance.CreateDatabase(); //创建数据库
            //sqlSugarClient.CodeFirst.SetStringDefaultLength(200).InitTables(typeof(Student));//创建表
        }

    }
}
